package com.xxl.job.executor.process;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.executor.SpringContextUtil;
import com.xxl.job.executor.model.GatherDefModel;
import com.xxl.job.executor.model.PowDownCmd;
import com.xxl.job.executor.model.SignalDefRqModel;
import com.xxl.job.executor.protocol.TCPProtocolCrc;
import com.xxl.job.executor.service.GatherDefService;
import com.xxl.job.executor.service.InvadesService;
import com.xxl.job.executor.service.PowDownCmdService;
import com.xxl.job.executor.utils.TransUtils;

import java.util.List;

/**
 * 文件描述
 *
 * @author wang.kunlin
 * @date 2020年09月10日 16:04
 */
public class InvadesProcess {

    TCPProtocolCrc tcpClient;
    //  最近的心跳时间
    long lastHeartbeat;
    // 心跳间隔时间
    long heartBeatInterval = 10 * 1000;
    private String param;
    private String err;
    private int str;

    public InvadesProcess(String param) {
        this.param = param;
    }


    public void collectProcess() throws Exception {

        try {
            for (int t = 0; t < 4000; t++) {
                XxlJobLogger.log("*************************************第" + t + "次******************************");

                List<GatherDefModel> gatherDefModelList = SpringContextUtil.getBean(GatherDefService.class)
                        .findGatherDefModelList(param);
                for (int num = 0; num < gatherDefModelList.size(); num++) {
                    String ip = gatherDefModelList.get(num).getCollectIp(); //获取IP
                    String gatherResId = gatherDefModelList.get(num).getResId();
                    int port = Integer.parseInt(gatherDefModelList.get(num).getCollectPort()); //获取端口
                    tcpClient = new TCPProtocolCrc(ip, port);
                    if (tcpClient.connect()) {
                        //发送RMT报文
                        tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>02RMT=5678<ETB>BF08<ETX>"));
                        //接收返回报文
                        Thread.sleep(1000);
                        //发送LCL报文
                        tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>04LCL<ETB>A527<ETX>"));
                        Thread.sleep(1000);
                        str = 0;
                        while (str < 30) {
                            long startTime = System.currentTimeMillis();
                            // 是否达到发送心跳的周期时间
                            if (startTime - lastHeartbeat > heartBeatInterval) {
                                lastHeartbeat = startTime;

                                tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>49CLOCK<ETB>2C65<ETX>"));
                             //   XxlJobLogger.log("---------------------发送心跳---------------------");
                                tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>32PSTT*1:4?<ETB>A048<ETX>"));//循环获取系统状态
                                tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>08ZSTT*1:4?<ETB>5C4D<ETX>"));//循环获取设备状态
                                tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>09ZSTT*5:8?<ETB>6378<ETX>"));//循环获取设备状态

                            }
                            downCmd();
                            try{
                                //接收返回报文
                                byte[] retByte = tcpClient.recvData();
                                String retStr = TransUtils.getBufHexStr(retByte);

                                if (retStr != "null" & retStr != null) {
                                    String recvMsg = TCPProtocolCrc.ascii2str(retStr).replace("<STX>04ACK<ETB>3927<ETX>", "");
                                 //   XxlJobLogger.log("消息体：" + recvMsg);
                                    if (recvMsg != "null" & recvMsg != null) {
                                        // 判断流水号
                                        String msgBody = recvMsg.split("<ETB>")[0].split("<STX>")[1];
                                        err=recvMsg;
                                        String liushuihao = msgBody.substring(0, 2);
                                        //XxlJobLogger.log("消息体：" + msgBody);

                                        // 判断命令及参数 判断是否有=
                                        if (msgBody.contains("=")) {
                                            String cmdStr = msgBody.substring(2).split("=")[0];
                                            String content = msgBody.substring(2).split("=")[1];
                                            if (!("49".equals(liushuihao) & "CLOCK".equals(cmdStr))) {// 心跳信息不处理
                                                if ("32".equals(liushuihao)) {
                                                    sendSave("PSTT1", content.substring(0, 16), gatherResId);
                                                } else if ("08".equals(liushuihao) || "09".equals(liushuihao)) {//批量设备状态信息处理
                                                    int a = 0;
                                                    int b = 0;
                                                    if (cmdStr.equals("ZSTT*1:4")) {
                                                        a = 1;
                                                        b = 5;
                                                    } else if (cmdStr.equals("ZSTT*5:8")) {
                                                        a = 5;
                                                        b = 9;
                                                    }
                                                    String content2 = content.replace("\t", "");
                                                    for (int i = a; i < b; i++) {
                                                        sendSave("ZSTT" + i, content2.substring((i - a) * 10, (i - a + 1) * 10), gatherResId);
                                                    }
                                                } else {
                                                    // 消息应答
                                                    String sendStr = liushuihao + "ACK<ETB>";
                                                    String crcCode = TCPProtocolCrc.getCRC(TCPProtocolCrc.ascii2crc16_2(sendStr));
                                                    String crcCodeLast = crcCode.substring(2, 4) + crcCode.substring(0, 2);
                                                    //   XxlJobLogger.log("应答内容：" + sendStr);
                                                    //  XxlJobLogger.log("应答CRC：" + crcCodeLast);
                                                    tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>" + liushuihao + "ACK<ETB>" + crcCodeLast + "<ETX>"));
                                                    //信号处理
                                                    sendSave(cmdStr, content, gatherResId);
                                                }

                                            }
                                        } else {
                                            String cmdStr = msgBody.substring(2);
                                            //    XxlJobLogger.log("消息指令：" + cmdStr);
                                        }


                                    } else {
                                        System.out.println(recvMsg);
                                    }
                                }

                            } catch (Exception e) {
                                System.out.println(err);
                                e.printStackTrace();
                            }



                            str++;
                         //   XxlJobLogger.log(" 循环" + str + "次");

                        }
                      //  XxlJobLogger.log(" 跳出循环");

                        tcpClient.close();

                    } else {
                        XxlJobLogger.log("入侵：client创建连接失败，等待30秒重连...，ip: " + ip + " ,port: " + port);
                        Thread.sleep(30000);
                    }
                }

             //   XxlJobLogger.log("*************************************暂停一秒******************************");
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            if (e instanceof InterruptedException) {
                throw e;
            }
            System.out.println(err);
            tcpClient.close();
            e.printStackTrace();
        }
    }


    public void sendSave(String cmdStr, String content, String gatherResId) {
        int flag = 0;
        if (cmdStr.indexOf("ZSTT") != -1) {
            String pointAddr = cmdStr.substring(4, 5);
            String value1 = "0";//撤防
            String value2 = "0";//正常
            if (content.substring(1, 2).equals("A")) {//布防
                value1 = "1";
            }
            if (content.substring(2, 3).equals("a")) {//报警
                value2 = "1";
            }
            SignalDefRqModel automaticControlModel = new SignalDefRqModel();
            automaticControlModel.setGatherId(param);
            automaticControlModel.setGatherResId(gatherResId);
            automaticControlModel.setPointAddr(pointAddr);
            automaticControlModel.setSignalType("02");
            automaticControlModel.setSignalValue(value1);
            SpringContextUtil.getBean(InvadesService.class).saves(automaticControlModel, flag);

            automaticControlModel.setSignalType("01");
            automaticControlModel.setSignalValue(value2);
            SpringContextUtil.getBean(InvadesService.class).saves(automaticControlModel, flag);
        }

        if (cmdStr.indexOf("PSTT") != -1) {
            String value3 = "0";//未准备
            if (content.substring(8, 9).equals("R")) {//准备
                value3 = "1";
            }
            SignalDefRqModel automaticControlModel = new SignalDefRqModel();
            automaticControlModel.setGatherId(param);
            automaticControlModel.setGatherResId(gatherResId);
            automaticControlModel.setSignalType("03");
            automaticControlModel.setSignalValue(value3);
            SpringContextUtil.getBean(InvadesService.class).save(automaticControlModel, flag);

        }

    }

    public void downCmd() {
        List<PowDownCmd> powDownCmds = SpringContextUtil.getBean(PowDownCmdService.class).getPowDownCmds(param);
        if (!(powDownCmds == null || powDownCmds.size() == 0)) {
            for (PowDownCmd powDownCmd : powDownCmds) {
                if ("1".equals(powDownCmd.getCmdStr())) {
                    XxlJobLogger.log("布防报文：<STX>02ARM=1<ETB>3F35<ETX>");
                    tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>02ARM=1<ETB>3F35<ETX>"));
                } else {
                    XxlJobLogger.log("撤防报文：<STX>02DISARM=1<ETB>6E99<ETX>");
                    tcpClient.sendData(TCPProtocolCrc.stringTo16ByteArr("<STX>02DISARM=1<ETB>6E99<ETX>"));
                }

            }
        }
    }

}
